import { CloseCircleFilled } from '@ant-design/icons'
import { useObservable } from '@gnlab/utils/env-react/rx'
import { Button } from 'antd'
import { Subject } from 'rxjs'
import SimpleChatRecord from '@/desktop/components/simple-chat-record'
import { usePasteFiles } from '@/desktop/logics/handle-drop-files'
import { useResize } from '@/desktop/logics/resize'
import Toolbar from '@/desktop/views/chat-toolbar'
import { useStreams } from '@/lib/utils'
import useUIMemory from '@/logics/memory'
import services from '@/services'
import { ChatRecordType } from '@/services/contact-chat'
import { type Contact, ContactType } from '@/services/contacts'
import { setRange } from '../utils'
import AtMembers, { type AtExportItem } from './at-members'
import { useInput } from './hooks'
import './index.module.less'

// 向编辑框推送文本内容
export const editorSubject = new Subject<string>()

export function ChatEditor(props: {
  contact: Contact
  sendFiles: (files: File[], autoStart?: boolean, recordType?: ChatRecordType) => void
}) {
  const { contact, sendFiles } = props

  const { onPaste } = usePasteFiles(sendFiles)

  const [atList, setAtList] = useState<AtExportItem[]>([])

  const send = useCallback(
    (text: string) => {
      void services.chat.send(ChatRecordType.Text, { atList, text })
      setAtList([])
    },
    [atList],
  )
  const { ref, insertText, onKeyPress, triggerSend } = useInput(send)

  const [quoted] = useStreams(services.chat.quoted)
  useEffect(() => {
    if (quoted) ref.current?.focus()
  }, [ref, quoted])

  // 处理草稿
  const contactId = contact.id
  useEffect(() => {
    const input = ref.current
    if (!input) return

    // 还原之前的草稿
    let draft = services.chat.drafts.drafts.value[contactId] ?? ''
    if (draft) input.innerText = draft
    services.chat.drafts.clear(contactId)

    // 记录此次聊天的草稿
    // onInput 事件在通过代码更新文本框内容时没反应，因此改为定时读取
    const intervalId = setInterval(() => {
      draft = input.innerText
    }, 500)

    return () => {
      clearInterval(intervalId)
      services.chat.drafts.save(contactId, draft.trim())
    }
  }, [contactId])

  // 处理外部推送的编辑框内容
  useObservable(editorSubject, content => {
    if (ref.current) {
      ref.current.innerText = content
      ref.current.focus()
      setRange(ref.current, content.length)
    }
  })

  const [editorSize, setEditorSize] = useUIMemory<number>('editor-size', 300)
  const resizeEvents = useResize({
    side: 'y',
    reverse: true,
    min: 150,
    max: () => document.body.clientHeight * 0.7,
    current: editorSize,
    onResize: setEditorSize,
  })

  return <div styleName="chat-editor" style={{ height: `${editorSize}px` }}>
    <div css={resizerStyle} {...resizeEvents}></div>
    <Toolbar insertText={insertText} sendFiles={sendFiles} />

    {quoted ? (
      <div styleName="quote">
        <div styleName="record">
          引用：
          <SimpleChatRecord record={quoted.record} />
        </div>
        <CloseCircleFilled onClick={() => services.chat.clearQuote()} />
      </div>
    ) : null}

    <div styleName="input-wrap">
      <div
        ref={ref}
        onKeyPress={onKeyPress}
        onPaste={onPaste}
        id="quntool-input"
        styleName="input"
        contentEditable
        spellCheck="false"
      ></div>

      <div styleName="placeholder">输入消息内容</div>

      {contact.type === ContactType.group ? (
        <AtMembers inputRef={ref} contact={contact} setAtList={setAtList} />
      ) : null}
    </div>

    <footer>
      <span>Enter 发送；Ctrl + Enter 换行</span>
      <Button
        type="primary"
        size="small"
        style={{ marginLeft: '1em', paddingLeft: '12px', paddingRight: '12px' }}
        onClick={triggerSend}
      >
        发送
      </Button>
    </footer>
  </div>
}

const resizerStyle = css`
  border-top: 1px solid #ddd;
  height: 5px;
  cursor: ns-resize;
`
